naider 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +884 -0
  3. package/SPEC-X.nx +276 -0
  4. package/SPEC.naide +431 -0
  5. package/bin/naide.js +519 -0
  6. package/examples/ai-app.naide +21 -0
  7. package/examples/ai-app.nx +21 -0
  8. package/examples/async.naide +50 -0
  9. package/examples/async.nx +40 -0
  10. package/examples/crud.naide +79 -0
  11. package/examples/crud.nx +64 -0
  12. package/examples/fullapp.naide +74 -0
  13. package/examples/fullapp.nx +74 -0
  14. package/examples/hello.naide +33 -0
  15. package/examples/hello.nx +29 -0
  16. package/examples/model.naide +44 -0
  17. package/examples/server.naide +28 -0
  18. package/examples/server.nx +27 -0
  19. package/examples/sql-app.naide +23 -0
  20. package/examples/sql-app.nx +23 -0
  21. package/examples/todo-api.naide +34 -0
  22. package/examples/todo-api.nx +31 -0
  23. package/lsp/server.js +172 -0
  24. package/package.json +56 -0
  25. package/src/generator.js +1313 -0
  26. package/src/index.js +41 -0
  27. package/src/lexer.js +402 -0
  28. package/src/parser.js +1671 -0
  29. package/src/preprocess.js +308 -0
  30. package/src/runtime.js +969 -0
  31. package/src/tokens.js +218 -0
  32. package/vscode-naide/README.md +38 -0
  33. package/vscode-naide/extension.js +41 -0
  34. package/vscode-naide/language-configuration-naide.json +32 -0
  35. package/vscode-naide/language-configuration-nx.json +32 -0
  36. package/vscode-naide/naide-lang-1.1.0.vsix +0 -0
  37. package/vscode-naide/node_modules/.bin/semver +16 -0
  38. package/vscode-naide/node_modules/.bin/semver.cmd +17 -0
  39. package/vscode-naide/node_modules/.bin/semver.ps1 +28 -0
  40. package/vscode-naide/node_modules/.package-lock.json +86 -0
  41. package/vscode-naide/node_modules/balanced-match/.github/FUNDING.yml +2 -0
  42. package/vscode-naide/node_modules/balanced-match/LICENSE.md +21 -0
  43. package/vscode-naide/node_modules/balanced-match/README.md +97 -0
  44. package/vscode-naide/node_modules/balanced-match/index.js +62 -0
  45. package/vscode-naide/node_modules/balanced-match/package.json +48 -0
  46. package/vscode-naide/node_modules/brace-expansion/.github/FUNDING.yml +2 -0
  47. package/vscode-naide/node_modules/brace-expansion/LICENSE +21 -0
  48. package/vscode-naide/node_modules/brace-expansion/README.md +157 -0
  49. package/vscode-naide/node_modules/brace-expansion/index.js +394 -0
  50. package/vscode-naide/node_modules/brace-expansion/package.json +49 -0
  51. package/vscode-naide/node_modules/minimatch/LICENSE +15 -0
  52. package/vscode-naide/node_modules/minimatch/README.md +296 -0
  53. package/vscode-naide/node_modules/minimatch/changelog.md +35 -0
  54. package/vscode-naide/node_modules/minimatch/lib/path.js +4 -0
  55. package/vscode-naide/node_modules/minimatch/minimatch.js +996 -0
  56. package/vscode-naide/node_modules/minimatch/package.json +35 -0
  57. package/vscode-naide/node_modules/semver/LICENSE +15 -0
  58. package/vscode-naide/node_modules/semver/README.md +680 -0
  59. package/vscode-naide/node_modules/semver/bin/semver.js +195 -0
  60. package/vscode-naide/node_modules/semver/classes/comparator.js +143 -0
  61. package/vscode-naide/node_modules/semver/classes/index.js +7 -0
  62. package/vscode-naide/node_modules/semver/classes/range.js +577 -0
  63. package/vscode-naide/node_modules/semver/classes/semver.js +350 -0
  64. package/vscode-naide/node_modules/semver/functions/clean.js +8 -0
  65. package/vscode-naide/node_modules/semver/functions/cmp.js +54 -0
  66. package/vscode-naide/node_modules/semver/functions/coerce.js +62 -0
  67. package/vscode-naide/node_modules/semver/functions/compare-build.js +9 -0
  68. package/vscode-naide/node_modules/semver/functions/compare-loose.js +5 -0
  69. package/vscode-naide/node_modules/semver/functions/compare.js +7 -0
  70. package/vscode-naide/node_modules/semver/functions/diff.js +60 -0
  71. package/vscode-naide/node_modules/semver/functions/eq.js +5 -0
  72. package/vscode-naide/node_modules/semver/functions/gt.js +5 -0
  73. package/vscode-naide/node_modules/semver/functions/gte.js +5 -0
  74. package/vscode-naide/node_modules/semver/functions/inc.js +21 -0
  75. package/vscode-naide/node_modules/semver/functions/lt.js +5 -0
  76. package/vscode-naide/node_modules/semver/functions/lte.js +5 -0
  77. package/vscode-naide/node_modules/semver/functions/major.js +5 -0
  78. package/vscode-naide/node_modules/semver/functions/minor.js +5 -0
  79. package/vscode-naide/node_modules/semver/functions/neq.js +5 -0
  80. package/vscode-naide/node_modules/semver/functions/parse.js +18 -0
  81. package/vscode-naide/node_modules/semver/functions/patch.js +5 -0
  82. package/vscode-naide/node_modules/semver/functions/prerelease.js +8 -0
  83. package/vscode-naide/node_modules/semver/functions/rcompare.js +5 -0
  84. package/vscode-naide/node_modules/semver/functions/rsort.js +5 -0
  85. package/vscode-naide/node_modules/semver/functions/satisfies.js +12 -0
  86. package/vscode-naide/node_modules/semver/functions/sort.js +5 -0
  87. package/vscode-naide/node_modules/semver/functions/truncate.js +48 -0
  88. package/vscode-naide/node_modules/semver/functions/valid.js +8 -0
  89. package/vscode-naide/node_modules/semver/index.js +93 -0
  90. package/vscode-naide/node_modules/semver/internal/constants.js +37 -0
  91. package/vscode-naide/node_modules/semver/internal/debug.js +11 -0
  92. package/vscode-naide/node_modules/semver/internal/identifiers.js +29 -0
  93. package/vscode-naide/node_modules/semver/internal/lrucache.js +42 -0
  94. package/vscode-naide/node_modules/semver/internal/parse-options.js +17 -0
  95. package/vscode-naide/node_modules/semver/internal/re.js +223 -0
  96. package/vscode-naide/node_modules/semver/package.json +78 -0
  97. package/vscode-naide/node_modules/semver/preload.js +4 -0
  98. package/vscode-naide/node_modules/semver/range.bnf +17 -0
  99. package/vscode-naide/node_modules/semver/ranges/gtr.js +6 -0
  100. package/vscode-naide/node_modules/semver/ranges/intersects.js +9 -0
  101. package/vscode-naide/node_modules/semver/ranges/ltr.js +6 -0
  102. package/vscode-naide/node_modules/semver/ranges/max-satisfying.js +27 -0
  103. package/vscode-naide/node_modules/semver/ranges/min-satisfying.js +26 -0
  104. package/vscode-naide/node_modules/semver/ranges/min-version.js +63 -0
  105. package/vscode-naide/node_modules/semver/ranges/outside.js +82 -0
  106. package/vscode-naide/node_modules/semver/ranges/simplify.js +49 -0
  107. package/vscode-naide/node_modules/semver/ranges/subset.js +249 -0
  108. package/vscode-naide/node_modules/semver/ranges/to-comparators.js +10 -0
  109. package/vscode-naide/node_modules/semver/ranges/valid.js +13 -0
  110. package/vscode-naide/node_modules/vscode-jsonrpc/License.txt +11 -0
  111. package/vscode-naide/node_modules/vscode-jsonrpc/README.md +69 -0
  112. package/vscode-naide/node_modules/vscode-jsonrpc/browser.d.ts +6 -0
  113. package/vscode-naide/node_modules/vscode-jsonrpc/browser.js +7 -0
  114. package/vscode-naide/node_modules/vscode-jsonrpc/lib/browser/main.d.ts +17 -0
  115. package/vscode-naide/node_modules/vscode-jsonrpc/lib/browser/main.js +76 -0
  116. package/vscode-naide/node_modules/vscode-jsonrpc/lib/browser/ril.d.ts +12 -0
  117. package/vscode-naide/node_modules/vscode-jsonrpc/lib/browser/ril.js +156 -0
  118. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/api.d.ts +14 -0
  119. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/api.js +81 -0
  120. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/cancellation.d.ts +32 -0
  121. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/cancellation.js +96 -0
  122. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/connection.d.ts +358 -0
  123. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/connection.js +1212 -0
  124. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/disposable.d.ts +9 -0
  125. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/disposable.js +16 -0
  126. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/encoding.d.ts +52 -0
  127. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/encoding.js +70 -0
  128. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/events.d.ts +39 -0
  129. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/events.js +128 -0
  130. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/is.d.ts +7 -0
  131. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/is.js +35 -0
  132. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/linkedMap.d.ts +53 -0
  133. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/linkedMap.js +398 -0
  134. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageBuffer.d.ts +18 -0
  135. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageBuffer.js +152 -0
  136. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageReader.d.ts +77 -0
  137. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageReader.js +197 -0
  138. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageWriter.d.ts +60 -0
  139. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageWriter.js +115 -0
  140. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messages.d.ts +369 -0
  141. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messages.js +306 -0
  142. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/ral.d.ts +74 -0
  143. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/ral.js +23 -0
  144. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/semaphore.d.ts +10 -0
  145. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/semaphore.js +68 -0
  146. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/sharedArrayCancellation.d.ts +15 -0
  147. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/sharedArrayCancellation.js +76 -0
  148. package/vscode-naide/node_modules/vscode-jsonrpc/lib/node/main.d.ts +63 -0
  149. package/vscode-naide/node_modules/vscode-jsonrpc/lib/node/main.js +257 -0
  150. package/vscode-naide/node_modules/vscode-jsonrpc/lib/node/ril.d.ts +13 -0
  151. package/vscode-naide/node_modules/vscode-jsonrpc/lib/node/ril.js +161 -0
  152. package/vscode-naide/node_modules/vscode-jsonrpc/node.cmd +5 -0
  153. package/vscode-naide/node_modules/vscode-jsonrpc/node.d.ts +6 -0
  154. package/vscode-naide/node_modules/vscode-jsonrpc/node.js +7 -0
  155. package/vscode-naide/node_modules/vscode-jsonrpc/package.json +45 -0
  156. package/vscode-naide/node_modules/vscode-jsonrpc/thirdpartynotices.txt +16 -0
  157. package/vscode-naide/node_modules/vscode-jsonrpc/typings/thenable.d.ts +5 -0
  158. package/vscode-naide/node_modules/vscode-languageclient/License.txt +11 -0
  159. package/vscode-naide/node_modules/vscode-languageclient/README.md +17 -0
  160. package/vscode-naide/node_modules/vscode-languageclient/browser.d.ts +6 -0
  161. package/vscode-naide/node_modules/vscode-languageclient/browser.js +7 -0
  162. package/vscode-naide/node_modules/vscode-languageclient/lib/browser/main.d.ts +8 -0
  163. package/vscode-naide/node_modules/vscode-languageclient/lib/browser/main.js +37 -0
  164. package/vscode-naide/node_modules/vscode-languageclient/lib/common/api.d.ts +36 -0
  165. package/vscode-naide/node_modules/vscode-languageclient/lib/common/api.js +27 -0
  166. package/vscode-naide/node_modules/vscode-languageclient/lib/common/callHierarchy.d.ts +37 -0
  167. package/vscode-naide/node_modules/vscode-languageclient/lib/common/callHierarchy.js +97 -0
  168. package/vscode-naide/node_modules/vscode-languageclient/lib/common/client.d.ts +476 -0
  169. package/vscode-naide/node_modules/vscode-languageclient/lib/common/client.js +1600 -0
  170. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeAction.d.ts +19 -0
  171. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeAction.js +99 -0
  172. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeConverter.d.ts +78 -0
  173. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeConverter.js +876 -0
  174. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeLens.d.ts +23 -0
  175. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeLens.js +78 -0
  176. package/vscode-naide/node_modules/vscode-languageclient/lib/common/colorProvider.d.ts +25 -0
  177. package/vscode-naide/node_modules/vscode-languageclient/lib/common/colorProvider.js +74 -0
  178. package/vscode-naide/node_modules/vscode-languageclient/lib/common/completion.d.ts +20 -0
  179. package/vscode-naide/node_modules/vscode-languageclient/lib/common/completion.js +126 -0
  180. package/vscode-naide/node_modules/vscode-languageclient/lib/common/configuration.d.ts +69 -0
  181. package/vscode-naide/node_modules/vscode-languageclient/lib/common/configuration.js +209 -0
  182. package/vscode-naide/node_modules/vscode-languageclient/lib/common/declaration.d.ts +16 -0
  183. package/vscode-naide/node_modules/vscode-languageclient/lib/common/declaration.js +54 -0
  184. package/vscode-naide/node_modules/vscode-languageclient/lib/common/definition.d.ts +16 -0
  185. package/vscode-naide/node_modules/vscode-languageclient/lib/common/definition.js +55 -0
  186. package/vscode-naide/node_modules/vscode-languageclient/lib/common/diagnostic.d.ts +122 -0
  187. package/vscode-naide/node_modules/vscode-languageclient/lib/common/diagnostic.js +814 -0
  188. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentHighlight.d.ts +15 -0
  189. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentHighlight.js +50 -0
  190. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentLink.d.ts +19 -0
  191. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentLink.js +71 -0
  192. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentSymbol.d.ts +17 -0
  193. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentSymbol.js +104 -0
  194. package/vscode-naide/node_modules/vscode-languageclient/lib/common/executeCommand.d.ts +21 -0
  195. package/vscode-naide/node_modules/vscode-languageclient/lib/common/executeCommand.js +72 -0
  196. package/vscode-naide/node_modules/vscode-languageclient/lib/common/features.d.ts +418 -0
  197. package/vscode-naide/node_modules/vscode-languageclient/lib/common/features.js +291 -0
  198. package/vscode-naide/node_modules/vscode-languageclient/lib/common/fileOperations.d.ts +116 -0
  199. package/vscode-naide/node_modules/vscode-languageclient/lib/common/fileOperations.js +333 -0
  200. package/vscode-naide/node_modules/vscode-languageclient/lib/common/fileSystemWatcher.d.ts +18 -0
  201. package/vscode-naide/node_modules/vscode-languageclient/lib/common/fileSystemWatcher.js +95 -0
  202. package/vscode-naide/node_modules/vscode-languageclient/lib/common/foldingRange.d.ts +19 -0
  203. package/vscode-naide/node_modules/vscode-languageclient/lib/common/foldingRange.js +65 -0
  204. package/vscode-naide/node_modules/vscode-languageclient/lib/common/formatting.d.ts +39 -0
  205. package/vscode-naide/node_modules/vscode-languageclient/lib/common/formatting.js +182 -0
  206. package/vscode-naide/node_modules/vscode-languageclient/lib/common/hover.d.ts +16 -0
  207. package/vscode-naide/node_modules/vscode-languageclient/lib/common/hover.js +58 -0
  208. package/vscode-naide/node_modules/vscode-languageclient/lib/common/implementation.d.ts +16 -0
  209. package/vscode-naide/node_modules/vscode-languageclient/lib/common/implementation.js +54 -0
  210. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlayHint.d.ts +20 -0
  211. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlayHint.js +92 -0
  212. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlineCompletion.d.ts +18 -0
  213. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlineCompletion.js +54 -0
  214. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlineValue.d.ts +18 -0
  215. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlineValue.js +65 -0
  216. package/vscode-naide/node_modules/vscode-languageclient/lib/common/linkedEditingRange.d.ts +21 -0
  217. package/vscode-naide/node_modules/vscode-languageclient/lib/common/linkedEditingRange.js +53 -0
  218. package/vscode-naide/node_modules/vscode-languageclient/lib/common/notebook.d.ts +96 -0
  219. package/vscode-naide/node_modules/vscode-languageclient/lib/common/notebook.js +851 -0
  220. package/vscode-naide/node_modules/vscode-languageclient/lib/common/progress.d.ts +11 -0
  221. package/vscode-naide/node_modules/vscode-languageclient/lib/common/progress.js +44 -0
  222. package/vscode-naide/node_modules/vscode-languageclient/lib/common/progressPart.d.ts +24 -0
  223. package/vscode-naide/node_modules/vscode-languageclient/lib/common/progressPart.js +96 -0
  224. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCallHierarchyItem.d.ts +6 -0
  225. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCallHierarchyItem.js +16 -0
  226. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCodeAction.d.ts +6 -0
  227. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCodeAction.js +14 -0
  228. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCodeLens.d.ts +5 -0
  229. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCodeLens.js +13 -0
  230. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCompletionItem.d.ts +11 -0
  231. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCompletionItem.js +13 -0
  232. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolConverter.d.ts +167 -0
  233. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolConverter.js +1134 -0
  234. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolDiagnostic.d.ts +18 -0
  235. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolDiagnostic.js +25 -0
  236. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolDocumentLink.d.ts +5 -0
  237. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolDocumentLink.js +13 -0
  238. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolInlayHint.d.ts +5 -0
  239. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolInlayHint.js +13 -0
  240. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolTypeHierarchyItem.d.ts +6 -0
  241. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolTypeHierarchyItem.js +16 -0
  242. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolWorkspaceSymbol.d.ts +7 -0
  243. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolWorkspaceSymbol.js +18 -0
  244. package/vscode-naide/node_modules/vscode-languageclient/lib/common/reference.d.ts +20 -0
  245. package/vscode-naide/node_modules/vscode-languageclient/lib/common/reference.js +53 -0
  246. package/vscode-naide/node_modules/vscode-languageclient/lib/common/rename.d.ts +27 -0
  247. package/vscode-naide/node_modules/vscode-languageclient/lib/common/rename.js +113 -0
  248. package/vscode-naide/node_modules/vscode-languageclient/lib/common/selectionRange.d.ts +16 -0
  249. package/vscode-naide/node_modules/vscode-languageclient/lib/common/selectionRange.js +57 -0
  250. package/vscode-naide/node_modules/vscode-languageclient/lib/common/semanticTokens.d.ts +33 -0
  251. package/vscode-naide/node_modules/vscode-languageclient/lib/common/semanticTokens.js +179 -0
  252. package/vscode-naide/node_modules/vscode-languageclient/lib/common/signatureHelp.d.ts +16 -0
  253. package/vscode-naide/node_modules/vscode-languageclient/lib/common/signatureHelp.js +71 -0
  254. package/vscode-naide/node_modules/vscode-languageclient/lib/common/textSynchronization.d.ts +101 -0
  255. package/vscode-naide/node_modules/vscode-languageclient/lib/common/textSynchronization.js +402 -0
  256. package/vscode-naide/node_modules/vscode-languageclient/lib/common/typeDefinition.d.ts +16 -0
  257. package/vscode-naide/node_modules/vscode-languageclient/lib/common/typeDefinition.js +55 -0
  258. package/vscode-naide/node_modules/vscode-languageclient/lib/common/typeHierarchy.d.ts +31 -0
  259. package/vscode-naide/node_modules/vscode-languageclient/lib/common/typeHierarchy.js +96 -0
  260. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/async.d.ts +41 -0
  261. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/async.js +276 -0
  262. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/is.d.ts +12 -0
  263. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/is.js +57 -0
  264. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/uuid.d.ts +22 -0
  265. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/uuid.js +97 -0
  266. package/vscode-naide/node_modules/vscode-languageclient/lib/common/workspaceFolder.d.ts +30 -0
  267. package/vscode-naide/node_modules/vscode-languageclient/lib/common/workspaceFolder.js +148 -0
  268. package/vscode-naide/node_modules/vscode-languageclient/lib/common/workspaceSymbol.d.ts +19 -0
  269. package/vscode-naide/node_modules/vscode-languageclient/lib/common/workspaceSymbol.js +79 -0
  270. package/vscode-naide/node_modules/vscode-languageclient/lib/node/main.d.ts +100 -0
  271. package/vscode-naide/node_modules/vscode-languageclient/lib/node/main.js +570 -0
  272. package/vscode-naide/node_modules/vscode-languageclient/lib/node/processes.d.ts +6 -0
  273. package/vscode-naide/node_modules/vscode-languageclient/lib/node/processes.js +47 -0
  274. package/vscode-naide/node_modules/vscode-languageclient/lib/node/terminateProcess.sh +16 -0
  275. package/vscode-naide/node_modules/vscode-languageclient/node.cmd +5 -0
  276. package/vscode-naide/node_modules/vscode-languageclient/node.d.ts +6 -0
  277. package/vscode-naide/node_modules/vscode-languageclient/node.js +7 -0
  278. package/vscode-naide/node_modules/vscode-languageclient/package.json +50 -0
  279. package/vscode-naide/node_modules/vscode-languageserver-protocol/License.txt +11 -0
  280. package/vscode-naide/node_modules/vscode-languageserver-protocol/README.md +16 -0
  281. package/vscode-naide/node_modules/vscode-languageserver-protocol/browser.d.ts +6 -0
  282. package/vscode-naide/node_modules/vscode-languageserver-protocol/browser.js +7 -0
  283. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/browser/main.d.ts +4 -0
  284. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/browser/main.js +28 -0
  285. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/api.d.ts +58 -0
  286. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/api.js +77 -0
  287. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/connection.d.ts +187 -0
  288. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/connection.js +15 -0
  289. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/messages.d.ts +51 -0
  290. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/messages.js +44 -0
  291. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.$.d.ts +1 -0
  292. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.$.js +43 -0
  293. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.callHierarchy.d.ts +86 -0
  294. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.callHierarchy.js +42 -0
  295. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.colorProvider.d.ts +66 -0
  296. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.colorProvider.js +32 -0
  297. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.configuration.d.ts +35 -0
  298. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.configuration.js +24 -0
  299. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.d.ts +3252 -0
  300. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.declaration.d.ts +37 -0
  301. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.declaration.js +22 -0
  302. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.diagnostic.d.ts +341 -0
  303. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.diagnostic.js +74 -0
  304. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.fileOperations.d.ts +306 -0
  305. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.fileOperations.js +101 -0
  306. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.foldingRange.d.ts +109 -0
  307. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.foldingRange.js +30 -0
  308. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.implementation.d.ts +38 -0
  309. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.implementation.js +21 -0
  310. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlayHint.d.ts +110 -0
  311. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlayHint.js +43 -0
  312. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlineCompletion.d.ts +57 -0
  313. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlineCompletion.js +22 -0
  314. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlineValue.d.ts +86 -0
  315. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlineValue.js +30 -0
  316. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.js +943 -0
  317. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.linkedEditingRange.d.ts +52 -0
  318. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.linkedEditingRange.js +19 -0
  319. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.moniker.d.ts +106 -0
  320. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.moniker.js +68 -0
  321. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.notebook.d.ts +400 -0
  322. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.notebook.js +214 -0
  323. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.progress.d.ts +107 -0
  324. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.progress.js +37 -0
  325. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.selectionRange.d.ts +41 -0
  326. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.selectionRange.js +20 -0
  327. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.semanticTokens.d.ts +223 -0
  328. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.semanticTokens.js +57 -0
  329. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.showDocument.d.ts +72 -0
  330. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.showDocument.js +22 -0
  331. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.typeDefinition.d.ts +38 -0
  332. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.typeDefinition.js +21 -0
  333. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.typeHierarchy.d.ts +83 -0
  334. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.typeHierarchy.js +42 -0
  335. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.workspaceFolder.d.ts +74 -0
  336. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.workspaceFolder.js +27 -0
  337. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/utils/is.d.ts +9 -0
  338. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/utils/is.js +46 -0
  339. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/node/main.d.ts +6 -0
  340. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/node/main.js +28 -0
  341. package/vscode-naide/node_modules/vscode-languageserver-protocol/metaModel.schema.json +783 -0
  342. package/vscode-naide/node_modules/vscode-languageserver-protocol/node.cmd +5 -0
  343. package/vscode-naide/node_modules/vscode-languageserver-protocol/node.d.ts +6 -0
  344. package/vscode-naide/node_modules/vscode-languageserver-protocol/node.js +7 -0
  345. package/vscode-naide/node_modules/vscode-languageserver-protocol/package.json +45 -0
  346. package/vscode-naide/node_modules/vscode-languageserver-protocol/thirdpartynotices.txt +31 -0
  347. package/vscode-naide/node_modules/vscode-languageserver-types/License.txt +11 -0
  348. package/vscode-naide/node_modules/vscode-languageserver-types/README.md +17 -0
  349. package/vscode-naide/node_modules/vscode-languageserver-types/lib/esm/main.d.ts +3139 -0
  350. package/vscode-naide/node_modules/vscode-languageserver-types/lib/esm/main.js +2222 -0
  351. package/vscode-naide/node_modules/vscode-languageserver-types/lib/esm/package.json +3 -0
  352. package/vscode-naide/node_modules/vscode-languageserver-types/lib/umd/main.d.ts +3139 -0
  353. package/vscode-naide/node_modules/vscode-languageserver-types/lib/umd/main.js +2272 -0
  354. package/vscode-naide/node_modules/vscode-languageserver-types/package.json +38 -0
  355. package/vscode-naide/node_modules/vscode-languageserver-types/thirdpartynotices.txt +16 -0
  356. package/vscode-naide/package-lock.json +96 -0
  357. package/vscode-naide/package.json +59 -0
  358. package/vscode-naide/syntaxes/naide.tmLanguage.json +194 -0
  359. package/vscode-naide/syntaxes/naidex.tmLanguage.json +287 -0
package/src/parser.js ADDED
@@ -0,0 +1,1671 @@
1
+ import { T, TYPE_TOKENS } from './tokens.js';
2
+
3
+ class ASTNode {
4
+ constructor(type, props = {}) {
5
+ this.type = type;
6
+ Object.assign(this, props);
7
+ }
8
+ }
9
+
10
+ export class Parser {
11
+ constructor(tokens) {
12
+ this.tokens = this.preprocessTokens(tokens.filter(t => t.type !== T.COMMENT));
13
+ this.pos = 0;
14
+ }
15
+
16
+ preprocessTokens(tokens) {
17
+ const result = [...tokens];
18
+ const indentsToRemove = new Set();
19
+
20
+ for (let i = 0; i < result.length; i++) {
21
+ if (result[i].type !== T.INDENT) continue;
22
+ let j = i + 1;
23
+ while (j < result.length && result[j].type === T.NEWLINE) j++;
24
+ if (j < result.length && result[j].type === T.PIPE) {
25
+ indentsToRemove.add(i);
26
+ }
27
+ }
28
+
29
+ if (indentsToRemove.size === 0) return result;
30
+
31
+ const dedentsToRemove = new Set();
32
+ for (const idx of indentsToRemove) {
33
+ let depth = 0;
34
+ for (let i = idx; i < result.length; i++) {
35
+ if (result[i].type === T.INDENT) depth++;
36
+ if (result[i].type === T.DEDENT) {
37
+ depth--;
38
+ if (depth === 0) {
39
+ dedentsToRemove.add(i);
40
+ break;
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ const allRemove = new Set([...indentsToRemove, ...dedentsToRemove]);
47
+ return result.filter((_, i) => !allRemove.has(i));
48
+ }
49
+
50
+ peek(offset = 0) {
51
+ const idx = this.pos + offset;
52
+ return idx < this.tokens.length ? this.tokens[idx] : { type: T.EOF, value: '' };
53
+ }
54
+
55
+ advance() {
56
+ const tok = this.tokens[this.pos];
57
+ this.pos++;
58
+ return tok;
59
+ }
60
+
61
+ expect(type) {
62
+ const tok = this.advance();
63
+ if (tok.type !== type) {
64
+ const hints = {
65
+ COLON: "Missing ':' — blocks (if, fn, server, etc.) need a colon at the end",
66
+ INDENT: "Expected an indented block — check your indentation (use 2 spaces)",
67
+ RPAREN: "Missing closing ')'",
68
+ RBRACKET: "Missing closing ']'",
69
+ RBRACE: "Missing closing '}'",
70
+ IDENT: "Expected an identifier (variable/function name)",
71
+ };
72
+ const hint = hints[type] ? `\n Hint: ${hints[type]}` : '';
73
+ throw this.error(`Expected ${type} but got ${tok.type} ('${tok.value}')${hint}`, tok);
74
+ }
75
+ return tok;
76
+ }
77
+
78
+ match(type) {
79
+ if (this.peek().type === type) {
80
+ return this.advance();
81
+ }
82
+ return null;
83
+ }
84
+
85
+ at(type) {
86
+ return this.peek().type === type;
87
+ }
88
+
89
+ atAny(...types) {
90
+ return types.includes(this.peek().type);
91
+ }
92
+
93
+ isIdentLike(type) {
94
+ return type === T.IDENT || TYPE_TOKENS.has(type) ||
95
+ type === T.LOG || type === T.DB || type === T.GET ||
96
+ type === T.POST || type === T.PUT || type === T.DEL ||
97
+ type === T.MATCH || type === T.ON || type === T.NEW ||
98
+ type === T.FROM || type === T.AS || type === T.SELF ||
99
+ type === T.SCHEMA || type === T.CRUD || type === T.AUTH ||
100
+ type === T.CORS || type === T.LIMIT || type === T.ENV ||
101
+ type === T.EVERY || type === T.WATCH || type === T.STATIC ||
102
+ type === T.WS || type === T.GROUP || type === T.COOKIE ||
103
+ type === T.NOT || type === T.AND || type === T.OR ||
104
+ type === T.IN || type === T.BREAK || type === T.CONTINUE ||
105
+ type === T.THROW || type === T.MUT || type === T.PUB ||
106
+ type === T.UPLOAD || type === T.SESSION || type === T.VIEW ||
107
+ type === T.SSE || type === T.CACHE || type === T.PATCH || type === T.MID ||
108
+ type === T.VALIDATE || type === T.TEST || type === T.ASSERT ||
109
+ type === T.QUEUE || type === T.JOB || type === T.OPENAPI ||
110
+ type === T.TYPEOF || type === T.INSTANCEOF || type === T.ENSURE ||
111
+ type === T.MODEL || type === T.PROMPT;
112
+ }
113
+
114
+ expectPropertyName() {
115
+ const tok = this.advance();
116
+ if (this.isIdentLike(tok.type)) {
117
+ return tok.value;
118
+ }
119
+ throw this.error(`Expected property name but got ${tok.type} ('${tok.value}')`, tok);
120
+ }
121
+
122
+ error(msg, tok) {
123
+ const t = tok || this.peek();
124
+ return new Error(`[NAIDE Parse Error] ${msg} at line ${t.line}:${t.col}`);
125
+ }
126
+
127
+ skipNewlines() {
128
+ while (this.at(T.NEWLINE)) this.advance();
129
+ }
130
+
131
+ skipWhitespace() {
132
+ while (this.atAny(T.NEWLINE, T.INDENT, T.DEDENT)) this.advance();
133
+ }
134
+
135
+ parse() {
136
+ const body = [];
137
+ this.skipNewlines();
138
+ while (!this.at(T.EOF)) {
139
+ const stmt = this.parseStatement();
140
+ if (stmt) body.push(stmt);
141
+ this.skipNewlines();
142
+ }
143
+ return new ASTNode('Program', { body });
144
+ }
145
+
146
+ parseStatement() {
147
+ this.skipNewlines();
148
+ const tok = this.peek();
149
+
150
+ switch (tok.type) {
151
+ case T.USE: return this.parseUse();
152
+ case T.FN: return this.parseFunction(false, false);
153
+ case T.FN_ASYNC: return this.parseFunction(true, false);
154
+ case T.PUB: return this.parsePub();
155
+ case T.RET: return this.parseReturn();
156
+ case T.IF: return this.parseIf();
157
+ case T.EACH: return this.parseEach();
158
+ case T.FOR: return this.parseFor();
159
+ case T.WHILE: return this.parseWhile();
160
+ case T.MATCH: return this.parseMatch();
161
+ case T.TRY: return this.parseTry();
162
+ case T.SERVER: return this.parseServer();
163
+ case T.MODEL: return this.parseModel();
164
+ case T.ON: return this.parseOn();
165
+ case T.LOG: return this.parseLog();
166
+ case T.THROW: return this.parseThrow();
167
+ case T.BREAK: this.advance(); return new ASTNode('Break');
168
+ case T.CONTINUE: this.advance(); return new ASTNode('Continue');
169
+ case T.MUT: return this.parseMutVariable();
170
+ case T.DB:
171
+ if (this.peek(1).type === T.DOT) return this.parseDbStatement();
172
+ return this.parseDbDir();
173
+ case T.AWAIT: return this.parseAwaitStatement();
174
+ case T.AWAIT_ALL: return this.parseAwaitAll();
175
+ case T.SCHEMA: return this.parseSchema();
176
+ case T.CRUD:
177
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
178
+ return this.parseCrud();
179
+ case T.AUTH:
180
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
181
+ return this.parseAuth();
182
+ case T.CORS:
183
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
184
+ return this.parseCors();
185
+ case T.LIMIT:
186
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
187
+ return this.parseLimit();
188
+ case T.ENV:
189
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
190
+ return this.parseEnv();
191
+ case T.EVERY:
192
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
193
+ return this.parseEvery();
194
+ case T.WATCH:
195
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
196
+ return this.parseWatch();
197
+ case T.STATIC:
198
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
199
+ return this.parseStatic();
200
+ case T.WS:
201
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
202
+ return this.parseWs();
203
+ case T.GROUP:
204
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
205
+ return this.parseGroup();
206
+ case T.COOKIE:
207
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
208
+ this.advance();
209
+ return new ASTNode('CookieDecl');
210
+ case T.VALIDATE:
211
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
212
+ return this.parseValidate();
213
+ case T.TEST:
214
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
215
+ return this.parseTest();
216
+ case T.ASSERT:
217
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
218
+ return this.parseAssert();
219
+ case T.QUEUE:
220
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
221
+ return this.parseQueue();
222
+ case T.PROMPT:
223
+ if (this.peek(1).type === T.DOT) return this.parseExpressionStatement();
224
+ return this.parsePrompt();
225
+ default:
226
+ if (TYPE_TOKENS.has(tok.type)) {
227
+ return this.parseTypedVariable();
228
+ }
229
+ return this.parseExpressionStatement();
230
+ }
231
+ }
232
+
233
+ parseUse() {
234
+ this.advance(); // use
235
+
236
+ if (this.at(T.LBRACE)) {
237
+ this.advance();
238
+ const names = [];
239
+ while (!this.at(T.RBRACE) && !this.at(T.EOF)) {
240
+ const tok = this.peek();
241
+ let name;
242
+ if (this.isIdentLike(tok.type)) {
243
+ name = this.advance().value;
244
+ } else {
245
+ name = this.expect(T.IDENT).value;
246
+ }
247
+ let alias = null;
248
+ if (this.match(T.AS)) {
249
+ alias = this.expect(T.IDENT).value;
250
+ }
251
+ names.push({ name, alias });
252
+ this.match(T.COMMA);
253
+ }
254
+ this.expect(T.RBRACE);
255
+ this.expect(T.FROM);
256
+ const source = this.parseString();
257
+ return new ASTNode('UseDestructured', { names, source });
258
+ }
259
+
260
+ const name = this.expect(T.IDENT).value;
261
+ let source = null;
262
+ let alias = null;
263
+
264
+ if (this.match(T.AS)) {
265
+ alias = this.expect(T.IDENT).value;
266
+ }
267
+
268
+ if (this.match(T.FROM)) {
269
+ source = this.parseString();
270
+ }
271
+
272
+ return new ASTNode('Use', { name, source, alias });
273
+ }
274
+
275
+ parseString() {
276
+ const tok = this.expect(T.STRING);
277
+ return tok.value;
278
+ }
279
+
280
+ parseFunction(isAsync, isPublic) {
281
+ this.advance(); // fn or fn.async
282
+ const tok = this.advance();
283
+ if (!this.isIdentLike(tok.type)) {
284
+ throw this.error(`Expected function name but got ${tok.type} ('${tok.value}')`, tok);
285
+ }
286
+ const name = tok.value;
287
+ this.expect(T.LPAREN);
288
+ const params = this.parseFnParams();
289
+ this.expect(T.RPAREN);
290
+
291
+ let returnType = null;
292
+ if (this.match(T.ARROW)) {
293
+ returnType = this.parseTypeAnnotation();
294
+ }
295
+
296
+ this.expect(T.COLON);
297
+ const body = this.parseBlock();
298
+
299
+ return new ASTNode('Function', { name, params, returnType, body, isAsync, isPublic });
300
+ }
301
+
302
+ parseFnParams() {
303
+ const params = [];
304
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
305
+ let type = null;
306
+ let spread = false;
307
+
308
+ if (this.match(T.SPREAD)) {
309
+ spread = true;
310
+ }
311
+
312
+ if (TYPE_TOKENS.has(this.peek().type)) {
313
+ type = this.advance().value;
314
+ }
315
+
316
+ const name = this.expect(T.IDENT).value;
317
+
318
+ let defaultValue = null;
319
+ if (this.match(T.ASSIGN)) {
320
+ defaultValue = this.parseExpression();
321
+ }
322
+
323
+ params.push({ name, type, defaultValue, spread });
324
+ this.match(T.COMMA);
325
+ }
326
+ return params;
327
+ }
328
+
329
+ parseTypeAnnotation() {
330
+ if (TYPE_TOKENS.has(this.peek().type)) {
331
+ return this.advance().value;
332
+ }
333
+ return this.expect(T.IDENT).value;
334
+ }
335
+
336
+ parseBlock() {
337
+ this.skipNewlines();
338
+ this.expect(T.INDENT);
339
+ const body = [];
340
+ this.skipNewlines();
341
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
342
+ const stmt = this.parseStatement();
343
+ if (stmt) body.push(stmt);
344
+ this.skipNewlines();
345
+ }
346
+ this.match(T.DEDENT);
347
+ return body;
348
+ }
349
+
350
+ parsePub() {
351
+ this.advance(); // pub
352
+ if (this.at(T.FN)) return this.parseFunction(false, true);
353
+ if (this.at(T.FN_ASYNC)) return this.parseFunction(true, true);
354
+ if (this.at(T.MODEL)) return this.parseModel(true);
355
+
356
+ if (TYPE_TOKENS.has(this.peek().type)) {
357
+ const node = this.parseTypedVariable();
358
+ node.isPublic = true;
359
+ return node;
360
+ }
361
+
362
+ throw this.error('Expected fn, model, or type after pub');
363
+ }
364
+
365
+ parseReturn() {
366
+ this.advance(); // ret
367
+ if (this.at(T.NEWLINE) || this.at(T.EOF) || this.at(T.DEDENT)) {
368
+ return new ASTNode('Return', { value: null });
369
+ }
370
+ if (this.match(T.DOT)) {
371
+ const method = this.expect(T.IDENT).value;
372
+ if (method === 'status') {
373
+ const statusCode = this.parseExpression();
374
+ const body = this.parseExpression();
375
+ return new ASTNode('ReturnStatus', { method, statusCode, body });
376
+ }
377
+ if (method === 'render') {
378
+ const template = this.parseExpression();
379
+ let data = null;
380
+ if (!this.at(T.NEWLINE) && !this.at(T.EOF) && !this.at(T.DEDENT)) {
381
+ data = this.parseExpression();
382
+ }
383
+ return new ASTNode('ReturnRender', { template, data });
384
+ }
385
+ if (method === 'redirect') {
386
+ const first = this.parseExpression();
387
+ if (!this.at(T.NEWLINE) && !this.at(T.EOF) && !this.at(T.DEDENT)) {
388
+ const url = this.parseExpression();
389
+ return new ASTNode('ReturnRedirect', { statusCode: first, url });
390
+ }
391
+ return new ASTNode('ReturnMethod', { method: 'redirect', value: first });
392
+ }
393
+ if (method === 'download') {
394
+ const filePath = this.parseExpression();
395
+ if (!this.at(T.NEWLINE) && !this.at(T.EOF) && !this.at(T.DEDENT)) {
396
+ const filename = this.parseExpression();
397
+ return new ASTNode('ReturnDownload', { filePath, filename });
398
+ }
399
+ return new ASTNode('ReturnMethod', { method: 'download', value: filePath });
400
+ }
401
+ const value = this.parseExpression();
402
+ return new ASTNode('ReturnMethod', { method, value });
403
+ }
404
+ const value = this.parseExpression();
405
+ return new ASTNode('Return', { value });
406
+ }
407
+
408
+ expectIdentLike() {
409
+ const tok = this.advance();
410
+ if (this.isIdentLike(tok.type)) return tok.value;
411
+ throw this.error(`Expected identifier but got ${tok.type} ('${tok.value}')`, tok);
412
+ }
413
+
414
+ parseTypedVariable() {
415
+ const varType = this.advance().value;
416
+ const name = this.expectIdentLike();
417
+ this.expect(T.ASSIGN);
418
+ const value = this.parseExpression();
419
+ return new ASTNode('TypedVar', { varType, name, value, isMut: false, isPublic: false });
420
+ }
421
+
422
+ parseMutVariable() {
423
+ this.advance(); // mut
424
+ if (TYPE_TOKENS.has(this.peek().type)) {
425
+ const node = this.parseTypedVariable();
426
+ node.isMut = true;
427
+ return node;
428
+ }
429
+ const name = this.expectIdentLike();
430
+ this.expect(T.ASSIGN);
431
+ const value = this.parseExpression();
432
+ return new ASTNode('TypedVar', { varType: null, name, value, isMut: true });
433
+ }
434
+
435
+ parseIf() {
436
+ this.advance(); // if
437
+ const condition = this.parseExpression();
438
+ this.expect(T.COLON);
439
+ const body = this.parseBlock();
440
+
441
+ const elifs = [];
442
+ this.skipNewlines();
443
+ while (this.at(T.ELIF)) {
444
+ this.advance();
445
+ const elifCond = this.parseExpression();
446
+ this.expect(T.COLON);
447
+ const elifBody = this.parseBlock();
448
+ elifs.push({ condition: elifCond, body: elifBody });
449
+ this.skipNewlines();
450
+ }
451
+
452
+ let elseBody = null;
453
+ if (this.at(T.ELSE)) {
454
+ this.advance();
455
+ this.expect(T.COLON);
456
+ elseBody = this.parseBlock();
457
+ }
458
+
459
+ return new ASTNode('If', { condition, body, elifs, elseBody });
460
+ }
461
+
462
+ parseEach() {
463
+ this.advance(); // each
464
+ let key = null;
465
+ const valueName = this.expect(T.IDENT).value;
466
+ if (this.match(T.COMMA)) {
467
+ key = valueName;
468
+ const val = this.expect(T.IDENT).value;
469
+ this.expect(T.IN);
470
+ const collection = this.parseExpression();
471
+ this.expect(T.COLON);
472
+ const body = this.parseBlock();
473
+ return new ASTNode('Each', { key, value: val, collection, body });
474
+ }
475
+ this.expect(T.IN);
476
+ const collection = this.parseExpression();
477
+ this.expect(T.COLON);
478
+ const body = this.parseBlock();
479
+ return new ASTNode('Each', { key: null, value: valueName, collection, body });
480
+ }
481
+
482
+ parseFor() {
483
+ this.advance(); // for
484
+ const varName = this.expect(T.IDENT).value;
485
+ this.expect(T.IN);
486
+ const start = this.parseExpression();
487
+ this.expect(T.RANGE);
488
+ const end = this.parseExpression();
489
+ this.expect(T.COLON);
490
+ const body = this.parseBlock();
491
+ return new ASTNode('For', { varName, start, end, body });
492
+ }
493
+
494
+ parseWhile() {
495
+ this.advance(); // while
496
+ const condition = this.parseExpression();
497
+ this.expect(T.COLON);
498
+ const body = this.parseBlock();
499
+ return new ASTNode('While', { condition, body });
500
+ }
501
+
502
+ parseMatch() {
503
+ this.advance(); // match
504
+ const value = this.parseExpression();
505
+ this.expect(T.COLON);
506
+ this.skipNewlines();
507
+ this.expect(T.INDENT);
508
+
509
+ const cases = [];
510
+ this.skipNewlines();
511
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
512
+ let pattern;
513
+ if (this.at(T.IDENT) && this.peek().value === '_') {
514
+ this.advance();
515
+ pattern = new ASTNode('DefaultPattern');
516
+ } else {
517
+ pattern = this.parseExpression();
518
+ }
519
+ this.expect(T.COLON);
520
+
521
+ let body;
522
+ if (this.at(T.NEWLINE) || this.at(T.INDENT)) {
523
+ this.skipNewlines();
524
+ if (this.at(T.INDENT)) {
525
+ body = this.parseBlock();
526
+ } else {
527
+ body = [this.parseStatement()];
528
+ }
529
+ } else {
530
+ body = [this.parseStatement()];
531
+ }
532
+ cases.push({ pattern, body });
533
+ this.skipNewlines();
534
+ }
535
+ this.match(T.DEDENT);
536
+ return new ASTNode('Match', { value, cases });
537
+ }
538
+
539
+ parseTry() {
540
+ this.advance(); // try
541
+ this.expect(T.COLON);
542
+ const body = this.parseBlock();
543
+
544
+ this.skipNewlines();
545
+ let catchVar = null;
546
+ let catchBody = null;
547
+ if (this.at(T.FAIL)) {
548
+ this.advance();
549
+ if (!this.at(T.COLON)) {
550
+ catchVar = this.expect(T.IDENT).value;
551
+ }
552
+ this.expect(T.COLON);
553
+ catchBody = this.parseBlock();
554
+ }
555
+
556
+ this.skipNewlines();
557
+ let ensureBody = null;
558
+ if (this.at(T.ENSURE)) {
559
+ this.advance();
560
+ this.expect(T.COLON);
561
+ ensureBody = this.parseBlock();
562
+ }
563
+
564
+ return new ASTNode('Try', { body, catchVar, catchBody, ensureBody });
565
+ }
566
+
567
+ parseServer() {
568
+ this.advance(); // server
569
+ const name = this.expect(T.IDENT).value;
570
+
571
+ let port = null;
572
+ if (this.at(T.IDENT) && this.peek().value === 'port') {
573
+ this.advance();
574
+ port = this.parseExpression();
575
+ }
576
+
577
+ this.expect(T.COLON);
578
+ this.skipNewlines();
579
+ this.expect(T.INDENT);
580
+
581
+ const routes = [];
582
+ const middleware = [];
583
+ this.skipNewlines();
584
+
585
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
586
+ if (this.atAny(T.GET, T.POST, T.PUT, T.DEL, T.PATCH)) {
587
+ routes.push(this.parseRoute());
588
+ } else if (this.at(T.MID)) {
589
+ const mid = this.parseMiddleware();
590
+ if (mid.type === 'MiddlewareRef') {
591
+ routes.push(mid);
592
+ } else {
593
+ middleware.push(mid);
594
+ }
595
+ } else if (this.at(T.CRUD)) {
596
+ routes.push(this.parseCrud());
597
+ } else if (this.at(T.AUTH)) {
598
+ routes.push(this.parseAuth());
599
+ } else if (this.at(T.CORS)) {
600
+ routes.push(this.parseCors());
601
+ } else if (this.at(T.LIMIT)) {
602
+ routes.push(this.parseLimit());
603
+ } else if (this.at(T.STATIC)) {
604
+ routes.push(this.parseStatic());
605
+ } else if (this.at(T.WS)) {
606
+ routes.push(this.parseWs());
607
+ } else if (this.at(T.GROUP)) {
608
+ routes.push(this.parseGroup());
609
+ } else if (this.at(T.COOKIE)) {
610
+ this.advance();
611
+ routes.push(new ASTNode('CookieDecl'));
612
+ } else if (this.at(T.UPLOAD)) {
613
+ routes.push(this.parseUpload());
614
+ } else if (this.at(T.SESSION)) {
615
+ routes.push(this.parseSession());
616
+ } else if (this.at(T.VIEW)) {
617
+ routes.push(this.parseView());
618
+ } else if (this.at(T.SSE)) {
619
+ routes.push(this.parseSse());
620
+ } else if (this.at(T.CACHE)) {
621
+ routes.push(this.parseCache());
622
+ } else if (this.at(T.VALIDATE)) {
623
+ routes.push(this.parseValidate());
624
+ } else if (this.at(T.OPENAPI)) {
625
+ routes.push(this.parseOpenapi());
626
+ } else if (this.at(T.QUEUE)) {
627
+ routes.push(this.parseQueue());
628
+ } else if (this.at(T.IDENT) && this.peek().value === 'error') {
629
+ routes.push(this.parseErrorHandler());
630
+ } else {
631
+ routes.push(this.parseStatement());
632
+ }
633
+ this.skipNewlines();
634
+ }
635
+ this.match(T.DEDENT);
636
+
637
+ return new ASTNode('Server', { name, port, routes, middleware });
638
+ }
639
+
640
+ parseRoute() {
641
+ const method = this.advance().value; // get/post/put/del
642
+ const path = this.parseString();
643
+
644
+ let middleware = [];
645
+ if (this.at(T.LBRACKET)) {
646
+ this.advance();
647
+ while (!this.at(T.RBRACKET) && !this.at(T.EOF)) {
648
+ middleware.push(this.parseExpression());
649
+ this.match(T.COMMA);
650
+ }
651
+ this.expect(T.RBRACKET);
652
+ }
653
+
654
+ let params = [];
655
+ if (this.match(T.LPAREN)) {
656
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
657
+ params.push(this.expect(T.IDENT).value);
658
+ this.match(T.COMMA);
659
+ }
660
+ this.expect(T.RPAREN);
661
+ }
662
+
663
+ let returnType = null;
664
+ if (this.match(T.ARROW)) {
665
+ returnType = this.parseTypeAnnotation();
666
+ }
667
+
668
+ this.expect(T.COLON);
669
+ const body = this.parseBlock();
670
+
671
+ return new ASTNode('Route', { method, path, middleware, params, returnType, body });
672
+ }
673
+
674
+ parseMiddleware() {
675
+ this.advance(); // mid
676
+ const name = this.expect(T.IDENT).value;
677
+ if (this.at(T.LPAREN)) {
678
+ this.advance();
679
+ const params = [];
680
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
681
+ params.push(this.expect(T.IDENT).value);
682
+ this.match(T.COMMA);
683
+ }
684
+ this.expect(T.RPAREN);
685
+ this.expect(T.COLON);
686
+ const body = this.parseBlock();
687
+ return new ASTNode('Middleware', { name, params, body });
688
+ }
689
+ let path = null;
690
+ if (this.at(T.STRING)) {
691
+ path = this.parseString();
692
+ }
693
+ return new ASTNode('MiddlewareRef', { name, path });
694
+ }
695
+
696
+ parseModel(isPublic = false) {
697
+ this.advance(); // model
698
+ const name = this.expect(T.IDENT).value;
699
+
700
+ let parent = null;
701
+ if (this.at(T.IDENT) && this.peek().value === 'extends') {
702
+ this.advance();
703
+ parent = this.expect(T.IDENT).value;
704
+ }
705
+
706
+ this.expect(T.COLON);
707
+ this.skipNewlines();
708
+ this.expect(T.INDENT);
709
+
710
+ const fields = [];
711
+ const methods = [];
712
+ this.skipNewlines();
713
+
714
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
715
+ if (this.at(T.FN) || this.at(T.FN_ASYNC)) {
716
+ const isAsync = this.at(T.FN_ASYNC);
717
+ methods.push(this.parseFunction(isAsync, false));
718
+ } else if (TYPE_TOKENS.has(this.peek().type)) {
719
+ const fieldType = this.advance().value;
720
+ const fieldName = this.expect(T.IDENT).value;
721
+ let defaultValue = null;
722
+ if (this.match(T.ASSIGN)) {
723
+ defaultValue = this.parseExpression();
724
+ }
725
+ fields.push({ name: fieldName, type: fieldType, defaultValue });
726
+ } else {
727
+ this.advance();
728
+ }
729
+ this.skipNewlines();
730
+ }
731
+ this.match(T.DEDENT);
732
+
733
+ return new ASTNode('Model', { name, parent, fields, methods, isPublic });
734
+ }
735
+
736
+ parseOn() {
737
+ this.advance(); // on
738
+ const event = this.parseExpression();
739
+ this.expect(T.COLON);
740
+ const body = this.parseBlock();
741
+ return new ASTNode('On', { event, body });
742
+ }
743
+
744
+ parseLog() {
745
+ this.advance(); // log
746
+ let level = 'log';
747
+ if (this.match(T.DOT)) {
748
+ level = this.expect(T.IDENT).value;
749
+ }
750
+ const args = [this.parseExpression()];
751
+ while (this.match(T.COMMA)) {
752
+ args.push(this.parseExpression());
753
+ }
754
+ return new ASTNode('Log', { level, args });
755
+ }
756
+
757
+ parseThrow() {
758
+ this.advance(); // throw
759
+ const value = this.parseExpression();
760
+ return new ASTNode('Throw', { value });
761
+ }
762
+
763
+ parseDbStatement() {
764
+ this.advance(); // db
765
+ this.expect(T.DOT);
766
+ const method = this.expect(T.IDENT).value;
767
+ if (method === 'connect') {
768
+ const connectionString = this.parseExpression();
769
+ return new ASTNode('DbConnect', { connectionString });
770
+ }
771
+ if (method === 'sql') {
772
+ const driver = this.parseString();
773
+ let connection = null;
774
+ if (this.at(T.STRING)) {
775
+ connection = this.parseString();
776
+ }
777
+ return new ASTNode('DbSql', { driver, connection });
778
+ }
779
+ this.pos -= 3;
780
+ return this.parseExpressionStatement();
781
+ }
782
+
783
+ parseDbDir() {
784
+ this.advance(); // db
785
+ const path = this.parseString();
786
+ return new ASTNode('DbDir', { path });
787
+ }
788
+
789
+ parseAwaitStatement() {
790
+ return this.parseExpressionStatement();
791
+ }
792
+
793
+ parseAwaitAll() {
794
+ this.advance(); // await.all
795
+ const exprs = [];
796
+ if (this.match(T.LBRACKET)) {
797
+ while (!this.at(T.RBRACKET) && !this.at(T.EOF)) {
798
+ this.skipWhitespace();
799
+ if (this.at(T.RBRACKET)) break;
800
+ exprs.push(this.parseExpression());
801
+ this.match(T.COMMA);
802
+ this.skipWhitespace();
803
+ }
804
+ this.expect(T.RBRACKET);
805
+ } else {
806
+ exprs.push(this.parseExpression());
807
+ }
808
+ return new ASTNode('AwaitAll', { expressions: exprs });
809
+ }
810
+
811
+ parseExpressionStatement() {
812
+ const expr = this.parseExpression();
813
+
814
+ if (this.match(T.ASSIGN)) {
815
+ const value = this.parseExpression();
816
+ return new ASTNode('Assignment', { target: expr, value });
817
+ }
818
+ if (this.match(T.PLUS_ASSIGN)) {
819
+ const value = this.parseExpression();
820
+ return new ASTNode('CompoundAssign', { target: expr, op: '+=', value });
821
+ }
822
+ if (this.match(T.MINUS_ASSIGN)) {
823
+ const value = this.parseExpression();
824
+ return new ASTNode('CompoundAssign', { target: expr, op: '-=', value });
825
+ }
826
+
827
+ return new ASTNode('ExprStatement', { expression: expr });
828
+ }
829
+
830
+ parseExpression() {
831
+ return this.parsePipe();
832
+ }
833
+
834
+ parsePipe() {
835
+ let left = this.parseTernary();
836
+ while (this.matchPipeAcrossLines()) {
837
+ this.skipWhitespace();
838
+ const right = this.parseTernary();
839
+ left = new ASTNode('Pipe', { left, right });
840
+ }
841
+ return left;
842
+ }
843
+
844
+ matchPipeAcrossLines() {
845
+ if (this.match(T.PIPE)) return true;
846
+ let scanPos = this.pos;
847
+ while (scanPos < this.tokens.length && this.tokens[scanPos].type === T.NEWLINE) {
848
+ scanPos++;
849
+ }
850
+ if (scanPos < this.tokens.length && this.tokens[scanPos].type === T.PIPE) {
851
+ while (this.at(T.NEWLINE)) this.advance();
852
+ this.advance();
853
+ return true;
854
+ }
855
+ return false;
856
+ }
857
+
858
+ parseTernary() {
859
+ if (this.at(T.IF)) {
860
+ const savedPos = this.pos;
861
+ this.advance();
862
+ const condition = this.parseNullish();
863
+ if (this.match(T.THEN)) {
864
+ const consequent = this.parseNullish();
865
+ this.expect(T.ELSE);
866
+ const alternate = this.parseNullish();
867
+ return new ASTNode('Ternary', { condition, consequent, alternate });
868
+ }
869
+ this.pos = savedPos;
870
+ }
871
+ let expr = this.parseNullish();
872
+ if (this.at(T.IF)) {
873
+ const savedPos = this.pos;
874
+ this.advance();
875
+ const condition = this.parseNullish();
876
+ if (this.match(T.THEN)) {
877
+ const consequent = this.parseNullish();
878
+ this.expect(T.ELSE);
879
+ const alternate = this.parseNullish();
880
+ return new ASTNode('Ternary', { condition, consequent, alternate });
881
+ }
882
+ this.pos = savedPos;
883
+ }
884
+ return expr;
885
+ }
886
+
887
+ parseNullish() {
888
+ let left = this.parseOr();
889
+ while (this.match(T.NULLISH)) {
890
+ const right = this.parseOr();
891
+ left = new ASTNode('Binary', { op: '??', left, right });
892
+ }
893
+ return left;
894
+ }
895
+
896
+ parseOr() {
897
+ let left = this.parseAnd();
898
+ while (this.match(T.OR)) {
899
+ const right = this.parseAnd();
900
+ left = new ASTNode('Binary', { op: '||', left, right });
901
+ }
902
+ return left;
903
+ }
904
+
905
+ parseAnd() {
906
+ let left = this.parseComparison();
907
+ while (this.match(T.AND)) {
908
+ const right = this.parseComparison();
909
+ left = new ASTNode('Binary', { op: '&&', left, right });
910
+ }
911
+ return left;
912
+ }
913
+
914
+ parseComparison() {
915
+ let left = this.parseAddition();
916
+ while (this.atAny(T.EQ, T.NEQ, T.GT, T.LT, T.GTE, T.LTE, T.INSTANCEOF)) {
917
+ const tok = this.advance();
918
+ const right = this.parseAddition();
919
+ if (tok.type === T.INSTANCEOF) {
920
+ left = new ASTNode('Binary', { op: 'instanceof', left, right });
921
+ } else {
922
+ left = new ASTNode('Binary', { op: tok.value === '==' ? '===' : tok.value === '!=' ? '!==' : tok.value, left, right });
923
+ }
924
+ }
925
+ return left;
926
+ }
927
+
928
+ parseAddition() {
929
+ let left = this.parseMultiplication();
930
+ while (this.atAny(T.PLUS, T.MINUS)) {
931
+ const op = this.advance().value;
932
+ const right = this.parseMultiplication();
933
+ left = new ASTNode('Binary', { op, left, right });
934
+ }
935
+ return left;
936
+ }
937
+
938
+ parseMultiplication() {
939
+ let left = this.parseUnary();
940
+ while (this.atAny(T.STAR, T.SLASH, T.PERCENT)) {
941
+ const op = this.advance().value;
942
+ const right = this.parseUnary();
943
+ left = new ASTNode('Binary', { op, left, right });
944
+ }
945
+ return left;
946
+ }
947
+
948
+ parseUnary() {
949
+ if (this.match(T.NOT)) {
950
+ const expr = this.parseUnary();
951
+ return new ASTNode('Unary', { op: '!', expr });
952
+ }
953
+ if (this.at(T.MINUS)) {
954
+ this.advance();
955
+ const expr = this.parseUnary();
956
+ return new ASTNode('Unary', { op: '-', expr });
957
+ }
958
+ if (this.match(T.AWAIT)) {
959
+ const expr = this.parseUnary();
960
+ return new ASTNode('Await', { expr });
961
+ }
962
+ if (this.at(T.AWAIT_ALL)) {
963
+ this.advance();
964
+ const expr = this.parsePostfix();
965
+ return new ASTNode('AwaitAllExpr', { expr });
966
+ }
967
+ if (this.match(T.SPREAD)) {
968
+ const expr = this.parseUnary();
969
+ return new ASTNode('Spread', { expr });
970
+ }
971
+ if (this.match(T.NEW)) {
972
+ const expr = this.parsePostfix();
973
+ return new ASTNode('New', { expr });
974
+ }
975
+ if (this.match(T.TYPEOF)) {
976
+ const expr = this.parseUnary();
977
+ return new ASTNode('TypeOf', { expr });
978
+ }
979
+ return this.parsePostfix();
980
+ }
981
+
982
+ parsePostfix() {
983
+ let expr = this.parsePrimary();
984
+
985
+ while (true) {
986
+ if (this.match(T.DOT)) {
987
+ const prop = this.expectPropertyName();
988
+ expr = new ASTNode('MemberAccess', { object: expr, property: prop });
989
+ } else if (this.match(T.OPTIONAL)) {
990
+ const prop = this.expectPropertyName();
991
+ expr = new ASTNode('OptionalAccess', { object: expr, property: prop });
992
+ } else if (this.at(T.LPAREN)) {
993
+ this.advance();
994
+ const args = this.parseArgList();
995
+ this.expect(T.RPAREN);
996
+ expr = new ASTNode('Call', { callee: expr, args });
997
+ } else if (this.at(T.LBRACKET)) {
998
+ this.advance();
999
+ const index = this.parseExpression();
1000
+ this.expect(T.RBRACKET);
1001
+ expr = new ASTNode('IndexAccess', { object: expr, index });
1002
+ } else {
1003
+ break;
1004
+ }
1005
+ }
1006
+
1007
+ return expr;
1008
+ }
1009
+
1010
+ parseArgList() {
1011
+ const args = [];
1012
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
1013
+ this.skipWhitespace();
1014
+ if (this.at(T.RPAREN)) break;
1015
+ args.push(this.parseExpression());
1016
+ this.match(T.COMMA);
1017
+ this.skipWhitespace();
1018
+ }
1019
+ return args;
1020
+ }
1021
+
1022
+ parsePrimary() {
1023
+ const tok = this.peek();
1024
+
1025
+ switch (tok.type) {
1026
+ case T.NUMBER:
1027
+ this.advance();
1028
+ return new ASTNode('Number', { value: tok.value });
1029
+
1030
+ case T.STRING:
1031
+ this.advance();
1032
+ return new ASTNode('String', { value: tok.value });
1033
+
1034
+ case T.BOOL:
1035
+ this.advance();
1036
+ return new ASTNode('Bool', { value: tok.value === 'true' });
1037
+
1038
+ case T.NULL:
1039
+ this.advance();
1040
+ return new ASTNode('Null');
1041
+
1042
+ case T.SELF:
1043
+ this.advance();
1044
+ return new ASTNode('Self');
1045
+
1046
+ case T.IDENT:
1047
+ this.advance();
1048
+ return new ASTNode('Identifier', { name: tok.value });
1049
+
1050
+ case T.TYPE_STR: case T.TYPE_INT: case T.TYPE_NUM:
1051
+ case T.TYPE_BOOL: case T.TYPE_LIST: case T.TYPE_MAP:
1052
+ case T.TYPE_ANY: case T.TYPE_JSON: case T.TYPE_VOID:
1053
+ this.advance();
1054
+ return new ASTNode('Identifier', { name: tok.value });
1055
+
1056
+ case T.SCHEMA: case T.CRUD: case T.AUTH: case T.CORS:
1057
+ case T.LIMIT: case T.ENV: case T.EVERY: case T.WATCH:
1058
+ case T.STATIC: case T.WS: case T.GROUP: case T.COOKIE:
1059
+ case T.UPLOAD: case T.SESSION: case T.VIEW: case T.SSE:
1060
+ case T.CACHE: case T.PATCH: case T.MID:
1061
+ case T.VALIDATE: case T.TEST: case T.ASSERT:
1062
+ case T.QUEUE: case T.JOB: case T.OPENAPI:
1063
+ case T.TYPEOF: case T.INSTANCEOF: case T.ENSURE:
1064
+ case T.PROMPT:
1065
+ case T.FROM: case T.AS: case T.IN:
1066
+ this.advance();
1067
+ return new ASTNode('Identifier', { name: tok.value });
1068
+
1069
+ case T.DB:
1070
+ return this.parseDbExpression();
1071
+
1072
+ case T.LOG:
1073
+ return this.parseLogExpression();
1074
+
1075
+ case T.LPAREN:
1076
+ return this.parseGroupOrArrow();
1077
+
1078
+ case T.LBRACKET:
1079
+ return this.parseArray();
1080
+
1081
+ case T.LBRACE:
1082
+ return this.parseObject();
1083
+
1084
+ case T.FN:
1085
+ case T.FN_ASYNC:
1086
+ return this.parseLambda();
1087
+
1088
+ default:
1089
+ throw this.error(`Unexpected token ${tok.type} ('${tok.value}')`);
1090
+ }
1091
+ }
1092
+
1093
+ parseDbExpression() {
1094
+ this.advance(); // db
1095
+ this.expect(T.DOT);
1096
+ const method = this.expect(T.IDENT).value;
1097
+ if (this.at(T.LPAREN)) {
1098
+ this.advance();
1099
+ const args = this.parseArgList();
1100
+ this.expect(T.RPAREN);
1101
+ return new ASTNode('Call', {
1102
+ callee: new ASTNode('MemberAccess', {
1103
+ object: new ASTNode('Identifier', { name: 'db' }),
1104
+ property: method
1105
+ }),
1106
+ args
1107
+ });
1108
+ }
1109
+ return new ASTNode('MemberAccess', {
1110
+ object: new ASTNode('Identifier', { name: 'db' }),
1111
+ property: method
1112
+ });
1113
+ }
1114
+
1115
+ parseLogExpression() {
1116
+ this.advance(); // log
1117
+ let level = 'log';
1118
+ if (this.match(T.DOT)) {
1119
+ level = this.expect(T.IDENT).value;
1120
+ }
1121
+ if (this.at(T.LPAREN)) {
1122
+ this.advance();
1123
+ const args = this.parseArgList();
1124
+ this.expect(T.RPAREN);
1125
+ return new ASTNode('Call', {
1126
+ callee: new ASTNode('MemberAccess', {
1127
+ object: new ASTNode('Identifier', { name: 'console' }),
1128
+ property: level
1129
+ }),
1130
+ args
1131
+ });
1132
+ }
1133
+ return new ASTNode('MemberAccess', {
1134
+ object: new ASTNode('Identifier', { name: 'console' }),
1135
+ property: level
1136
+ });
1137
+ }
1138
+
1139
+ parseGroupOrArrow() {
1140
+ const savedPos = this.pos;
1141
+ this.advance(); // (
1142
+
1143
+ let isArrow = false;
1144
+ let depth = 1;
1145
+ let scanPos = this.pos;
1146
+ while (scanPos < this.tokens.length && depth > 0) {
1147
+ if (this.tokens[scanPos].type === T.LPAREN) depth++;
1148
+ if (this.tokens[scanPos].type === T.RPAREN) depth--;
1149
+ scanPos++;
1150
+ }
1151
+ if (scanPos < this.tokens.length && this.tokens[scanPos].type === T.FAT_ARROW) {
1152
+ isArrow = true;
1153
+ }
1154
+
1155
+ if (isArrow) {
1156
+ const params = [];
1157
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
1158
+ let type = null;
1159
+ if (TYPE_TOKENS.has(this.peek().type)) {
1160
+ type = this.advance().value;
1161
+ }
1162
+ const name = this.expect(T.IDENT).value;
1163
+ params.push({ name, type });
1164
+ this.match(T.COMMA);
1165
+ }
1166
+ this.expect(T.RPAREN);
1167
+ this.expect(T.FAT_ARROW);
1168
+ const body = this.parseExpression();
1169
+ return new ASTNode('ArrowFn', { params, body });
1170
+ }
1171
+
1172
+ this.pos = savedPos;
1173
+ this.advance(); // (
1174
+ const expr = this.parseExpression();
1175
+ this.expect(T.RPAREN);
1176
+ return expr;
1177
+ }
1178
+
1179
+ parseArray() {
1180
+ this.advance(); // [
1181
+ const elements = [];
1182
+ while (!this.at(T.RBRACKET) && !this.at(T.EOF)) {
1183
+ this.skipWhitespace();
1184
+ if (this.at(T.RBRACKET)) break;
1185
+ elements.push(this.parseExpression());
1186
+ this.match(T.COMMA);
1187
+ this.skipWhitespace();
1188
+ }
1189
+ this.expect(T.RBRACKET);
1190
+ return new ASTNode('Array', { elements });
1191
+ }
1192
+
1193
+ parseObject() {
1194
+ this.advance(); // {
1195
+ const properties = [];
1196
+ while (!this.at(T.RBRACE) && !this.at(T.EOF)) {
1197
+ this.skipWhitespace();
1198
+ if (this.at(T.RBRACE)) break;
1199
+
1200
+ if (this.match(T.SPREAD)) {
1201
+ const expr = this.parseExpression();
1202
+ properties.push({ type: 'spread', value: expr });
1203
+ this.match(T.COMMA);
1204
+ this.skipWhitespace();
1205
+ continue;
1206
+ }
1207
+
1208
+ let key;
1209
+ if (this.at(T.STRING)) {
1210
+ key = this.parseString();
1211
+ key = new ASTNode('String', { value: key });
1212
+ } else if (this.at(T.LBRACKET)) {
1213
+ this.advance();
1214
+ key = this.parseExpression();
1215
+ this.expect(T.RBRACKET);
1216
+ key = new ASTNode('Computed', { expr: key });
1217
+ } else {
1218
+ const tok = this.peek();
1219
+ if (this.isIdentLike(tok.type)) {
1220
+ key = this.advance().value;
1221
+ } else {
1222
+ key = this.expect(T.IDENT).value;
1223
+ }
1224
+ }
1225
+
1226
+ if (this.match(T.COLON)) {
1227
+ const value = this.parseExpression();
1228
+ properties.push({ type: 'property', key, value });
1229
+ } else {
1230
+ properties.push({ type: 'shorthand', key });
1231
+ }
1232
+ this.match(T.COMMA);
1233
+ this.skipWhitespace();
1234
+ }
1235
+ this.expect(T.RBRACE);
1236
+ return new ASTNode('Object', { properties });
1237
+ }
1238
+
1239
+ parseLambda() {
1240
+ const isAsync = this.at(T.FN_ASYNC);
1241
+ this.advance(); // fn or fn.async
1242
+ this.expect(T.LPAREN);
1243
+ const params = this.parseFnParams();
1244
+ this.expect(T.RPAREN);
1245
+ let returnType = null;
1246
+ if (this.match(T.ARROW)) {
1247
+ returnType = this.parseTypeAnnotation();
1248
+ }
1249
+ this.expect(T.COLON);
1250
+ const body = this.parseBlock();
1251
+ return new ASTNode('Lambda', { params, returnType, body, isAsync });
1252
+ }
1253
+
1254
+ // ===== High-level feature parsers =====
1255
+
1256
+ parseSchema() {
1257
+ this.advance(); // schema
1258
+ const name = this.expect(T.IDENT).value;
1259
+ this.expect(T.COLON);
1260
+ this.skipNewlines();
1261
+ this.expect(T.INDENT);
1262
+
1263
+ const fields = [];
1264
+ this.skipNewlines();
1265
+
1266
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
1267
+ fields.push(this.parseSchemaField());
1268
+ this.skipNewlines();
1269
+ }
1270
+ this.match(T.DEDENT);
1271
+
1272
+ return new ASTNode('SchemaDecl', { name, fields });
1273
+ }
1274
+
1275
+ parseSchemaField() {
1276
+ const name = this.expect(T.IDENT).value;
1277
+
1278
+ let fieldType;
1279
+ let enumValues = null;
1280
+
1281
+ if (TYPE_TOKENS.has(this.peek().type)) {
1282
+ fieldType = this.advance().value;
1283
+ } else if (this.at(T.IDENT)) {
1284
+ fieldType = this.advance().value;
1285
+ if (fieldType === 'enum' && this.at(T.LPAREN)) {
1286
+ this.advance();
1287
+ enumValues = [];
1288
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
1289
+ enumValues.push(this.parseExpression());
1290
+ this.match(T.COMMA);
1291
+ }
1292
+ this.expect(T.RPAREN);
1293
+ }
1294
+ } else {
1295
+ throw this.error('Expected type in schema field');
1296
+ }
1297
+
1298
+ const modifiers = [];
1299
+ while (!this.at(T.NEWLINE) && !this.at(T.DEDENT) && !this.at(T.EOF)) {
1300
+ if (this.at(T.IDENT) || this.at(T.IDENT)) {
1301
+ const modName = this.advance().value;
1302
+ if (this.at(T.LPAREN)) {
1303
+ this.advance();
1304
+ const args = [];
1305
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
1306
+ args.push(this.parseExpression());
1307
+ this.match(T.COMMA);
1308
+ }
1309
+ this.expect(T.RPAREN);
1310
+ modifiers.push({ name: modName, args });
1311
+ } else {
1312
+ modifiers.push({ name: modName, args: [] });
1313
+ }
1314
+ } else {
1315
+ break;
1316
+ }
1317
+ }
1318
+
1319
+ return { name, type: fieldType, enumValues, modifiers };
1320
+ }
1321
+
1322
+ parseCrud() {
1323
+ this.advance(); // crud
1324
+ const path = this.parseString();
1325
+ const schemaName = this.expect(T.IDENT).value;
1326
+ return new ASTNode('CrudDecl', { path, schemaName });
1327
+ }
1328
+
1329
+ parseAuth() {
1330
+ this.advance(); // auth
1331
+ const secret = this.parseExpression();
1332
+
1333
+ const protectedPaths = [];
1334
+ const publicPaths = [];
1335
+
1336
+ if (this.match(T.COLON)) {
1337
+ this.skipNewlines();
1338
+ this.expect(T.INDENT);
1339
+ this.skipNewlines();
1340
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
1341
+ if (this.at(T.IDENT) && this.peek().value === 'protect') {
1342
+ this.advance();
1343
+ protectedPaths.push(this.parseString());
1344
+ } else if (this.at(T.IDENT) && this.peek().value === 'public') {
1345
+ this.advance();
1346
+ publicPaths.push(this.parseString());
1347
+ } else {
1348
+ this.advance();
1349
+ }
1350
+ this.skipNewlines();
1351
+ }
1352
+ this.match(T.DEDENT);
1353
+ }
1354
+
1355
+ return new ASTNode('AuthDecl', { secret, protectedPaths, publicPaths });
1356
+ }
1357
+
1358
+ parseCors() {
1359
+ this.advance(); // cors
1360
+ const origins = this.parseExpression();
1361
+ return new ASTNode('CorsDecl', { origins });
1362
+ }
1363
+
1364
+ parseLimit() {
1365
+ this.advance(); // limit
1366
+ const path = this.parseString();
1367
+ const max = this.parseExpression();
1368
+ const window = this.parseExpression();
1369
+ return new ASTNode('LimitDecl', { path, max, window });
1370
+ }
1371
+
1372
+ parseEnv() {
1373
+ this.advance(); // env
1374
+ this.expect(T.COLON);
1375
+ this.skipNewlines();
1376
+ this.expect(T.INDENT);
1377
+
1378
+ const vars = [];
1379
+ this.skipNewlines();
1380
+
1381
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
1382
+ vars.push(this.parseEnvField());
1383
+ this.skipNewlines();
1384
+ }
1385
+ this.match(T.DEDENT);
1386
+
1387
+ return new ASTNode('EnvDecl', { vars });
1388
+ }
1389
+
1390
+ parseEnvField() {
1391
+ const name = this.expect(T.IDENT).value;
1392
+
1393
+ let fieldType = 'string';
1394
+ if (TYPE_TOKENS.has(this.peek().type)) {
1395
+ fieldType = this.advance().value;
1396
+ } else if (this.at(T.IDENT) && ['string', 'number', 'integer', 'boolean'].includes(this.peek().value)) {
1397
+ fieldType = this.advance().value;
1398
+ }
1399
+
1400
+ const modifiers = [];
1401
+ while (!this.at(T.NEWLINE) && !this.at(T.DEDENT) && !this.at(T.EOF)) {
1402
+ if (this.at(T.IDENT)) {
1403
+ const modName = this.advance().value;
1404
+ if (this.at(T.LPAREN)) {
1405
+ this.advance();
1406
+ const args = [];
1407
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
1408
+ args.push(this.parseExpression());
1409
+ this.match(T.COMMA);
1410
+ }
1411
+ this.expect(T.RPAREN);
1412
+ modifiers.push({ name: modName, args });
1413
+ } else {
1414
+ modifiers.push({ name: modName, args: [] });
1415
+ }
1416
+ } else {
1417
+ break;
1418
+ }
1419
+ }
1420
+
1421
+ return { name, type: fieldType, modifiers };
1422
+ }
1423
+
1424
+ parseEvery() {
1425
+ this.advance(); // every
1426
+ const interval = this.parseExpression();
1427
+ this.expect(T.COLON);
1428
+ const body = this.parseBlock();
1429
+ return new ASTNode('EveryDecl', { interval, body });
1430
+ }
1431
+
1432
+ parseWatch() {
1433
+ this.advance(); // watch
1434
+ let eventName = this.expect(T.IDENT).value;
1435
+ while (this.match(T.DOT)) {
1436
+ eventName += '.' + this.expectPropertyName();
1437
+ }
1438
+ let params = [];
1439
+ if (this.match(T.LPAREN)) {
1440
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
1441
+ params.push(this.expect(T.IDENT).value);
1442
+ this.match(T.COMMA);
1443
+ }
1444
+ this.expect(T.RPAREN);
1445
+ }
1446
+ this.expect(T.COLON);
1447
+ const body = this.parseBlock();
1448
+ return new ASTNode('WatchDecl', { eventName, params, body });
1449
+ }
1450
+
1451
+ // static "/public"
1452
+ parseStatic() {
1453
+ this.advance(); // static
1454
+ const path = this.parseString();
1455
+ return new ASTNode('StaticDecl', { path });
1456
+ }
1457
+
1458
+ // ws "/chat":
1459
+ // on "message" (data):
1460
+ // broadcast(data)
1461
+ // on "connect":
1462
+ // send({type: "welcome"})
1463
+ parseWs() {
1464
+ this.advance(); // ws
1465
+ const path = this.parseString();
1466
+ this.expect(T.COLON);
1467
+ this.skipNewlines();
1468
+ this.expect(T.INDENT);
1469
+
1470
+ const events = [];
1471
+ this.skipNewlines();
1472
+
1473
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
1474
+ if (this.at(T.ON)) {
1475
+ this.advance(); // on
1476
+ const eventName = this.parseString();
1477
+ let params = [];
1478
+ if (this.match(T.LPAREN)) {
1479
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
1480
+ params.push(this.expect(T.IDENT).value);
1481
+ this.match(T.COMMA);
1482
+ }
1483
+ this.expect(T.RPAREN);
1484
+ }
1485
+ this.expect(T.COLON);
1486
+ const body = this.parseBlock();
1487
+ events.push({ name: eventName, params, body });
1488
+ } else {
1489
+ this.advance();
1490
+ }
1491
+ this.skipNewlines();
1492
+ }
1493
+ this.match(T.DEDENT);
1494
+
1495
+ return new ASTNode('WsDecl', { path, events });
1496
+ }
1497
+
1498
+ parseGroup() {
1499
+ this.advance(); // group
1500
+ const prefix = this.parseString();
1501
+ this.expect(T.COLON);
1502
+ this.skipNewlines();
1503
+ this.expect(T.INDENT);
1504
+
1505
+ const routes = [];
1506
+ this.skipNewlines();
1507
+
1508
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
1509
+ if (this.atAny(T.GET, T.POST, T.PUT, T.DEL, T.PATCH)) {
1510
+ routes.push(this.parseRoute());
1511
+ } else if (this.at(T.MID)) {
1512
+ routes.push(this.parseMiddleware());
1513
+ } else if (this.at(T.CRUD)) {
1514
+ routes.push(this.parseCrud());
1515
+ } else if (this.at(T.AUTH)) {
1516
+ routes.push(this.parseAuth());
1517
+ } else if (this.at(T.GROUP)) {
1518
+ routes.push(this.parseGroup());
1519
+ } else {
1520
+ routes.push(this.parseStatement());
1521
+ }
1522
+ this.skipNewlines();
1523
+ }
1524
+ this.match(T.DEDENT);
1525
+
1526
+ return new ASTNode('GroupDecl', { prefix, routes });
1527
+ }
1528
+
1529
+ parseErrorHandler() {
1530
+ this.advance(); // error (ident)
1531
+ let params = ['err', 'req', 'res'];
1532
+ if (this.match(T.LPAREN)) {
1533
+ params = [];
1534
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
1535
+ params.push(this.expect(T.IDENT).value);
1536
+ this.match(T.COMMA);
1537
+ }
1538
+ this.expect(T.RPAREN);
1539
+ }
1540
+ this.expect(T.COLON);
1541
+ const body = this.parseBlock();
1542
+ return new ASTNode('ErrorHandler', { params, body });
1543
+ }
1544
+
1545
+ parseUpload() {
1546
+ this.advance(); // upload
1547
+ const path = this.parseString();
1548
+ const fieldName = this.parseString();
1549
+ let params = [];
1550
+ if (this.match(T.LPAREN)) {
1551
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
1552
+ params.push(this.expect(T.IDENT).value);
1553
+ this.match(T.COMMA);
1554
+ }
1555
+ this.expect(T.RPAREN);
1556
+ }
1557
+ this.expect(T.COLON);
1558
+ const body = this.parseBlock();
1559
+ return new ASTNode('UploadDecl', { path, fieldName, params, body });
1560
+ }
1561
+
1562
+ parseSession() {
1563
+ this.advance(); // session
1564
+ const secret = this.parseExpression();
1565
+ return new ASTNode('SessionDecl', { secret });
1566
+ }
1567
+
1568
+ parseView() {
1569
+ this.advance(); // view
1570
+ const dir = this.parseString();
1571
+ return new ASTNode('ViewDecl', { dir });
1572
+ }
1573
+
1574
+ parseSse() {
1575
+ this.advance(); // sse
1576
+ const path = this.parseString();
1577
+ return new ASTNode('SseDecl', { path });
1578
+ }
1579
+
1580
+ parseCache() {
1581
+ this.advance(); // cache
1582
+ const path = this.parseString();
1583
+ const duration = this.parseExpression();
1584
+ return new ASTNode('CacheDecl', { path, duration });
1585
+ }
1586
+
1587
+ parseValidate() {
1588
+ this.advance(); // validate
1589
+ const path = this.parseString();
1590
+ const schemaName = this.expect(T.IDENT).value;
1591
+ return new ASTNode('ValidateDecl', { path, schemaName });
1592
+ }
1593
+
1594
+ parseTest() {
1595
+ this.advance(); // test
1596
+ const name = this.parseExpression();
1597
+ this.expect(T.COLON);
1598
+ const body = this.parseBlock();
1599
+ return new ASTNode('TestDecl', { name, body });
1600
+ }
1601
+
1602
+ parseAssert() {
1603
+ this.advance(); // assert
1604
+ const expr = this.parseExpression();
1605
+ return new ASTNode('AssertStmt', { expr });
1606
+ }
1607
+
1608
+ parseQueue() {
1609
+ this.advance(); // queue
1610
+ const name = this.expect(T.IDENT).value;
1611
+ this.expect(T.COLON);
1612
+ this.skipNewlines();
1613
+ this.expect(T.INDENT);
1614
+
1615
+ const jobs = [];
1616
+ this.skipNewlines();
1617
+
1618
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
1619
+ if (this.at(T.JOB)) {
1620
+ this.advance();
1621
+ const jobName = this.parseString();
1622
+ let params = [];
1623
+ if (this.match(T.LPAREN)) {
1624
+ while (!this.at(T.RPAREN) && !this.at(T.EOF)) {
1625
+ params.push(this.expect(T.IDENT).value);
1626
+ this.match(T.COMMA);
1627
+ }
1628
+ this.expect(T.RPAREN);
1629
+ }
1630
+ this.expect(T.COLON);
1631
+ const body = this.parseBlock();
1632
+ jobs.push({ name: jobName, params, body });
1633
+ } else {
1634
+ this.advance();
1635
+ }
1636
+ this.skipNewlines();
1637
+ }
1638
+ this.match(T.DEDENT);
1639
+
1640
+ return new ASTNode('QueueDecl', { name, jobs });
1641
+ }
1642
+
1643
+ parseOpenapi() {
1644
+ this.advance(); // openapi
1645
+ const path = this.parseString();
1646
+ return new ASTNode('OpenapiDecl', { path });
1647
+ }
1648
+
1649
+ parsePrompt() {
1650
+ this.advance(); // prompt
1651
+ const name = this.expect(T.IDENT).value;
1652
+ let defaults = null;
1653
+ if (this.at(T.LBRACE)) {
1654
+ defaults = this.parseObject();
1655
+ }
1656
+ this.expect(T.COLON);
1657
+ this.skipNewlines();
1658
+ this.expect(T.INDENT);
1659
+ const lines = [];
1660
+ while (!this.at(T.DEDENT) && !this.at(T.EOF)) {
1661
+ if (this.at(T.STRING)) {
1662
+ lines.push(this.parseString());
1663
+ } else {
1664
+ this.advance();
1665
+ }
1666
+ this.skipNewlines();
1667
+ }
1668
+ this.match(T.DEDENT);
1669
+ return new ASTNode('PromptDecl', { name, defaults, lines });
1670
+ }
1671
+ }